
#include <BSizeStretch>
#include <BSplitter>
#include "member_BSplitter.h"

using namespace BWE;

member_BSplitter::member_BSplitter(BSplitter* splitter)
{
	boss = splitter;
	orientation = Orientation_Horizontal;
	dirty = false;
	holding = false;
	handle = 5;
	handleIndex = -1;
}
member_BSplitter::~member_BSplitter()
{

}

void member_BSplitter::slotShow(BObject* object, const BValue& value)
{
	adjust();
	boss->fresh();
}
void member_BSplitter::slotHide(BObject* object, const BValue& value)
{
	adjust();
	boss->fresh();
}

BRect member_BSplitter::handleRect(int index)
{
	if (BWidget* widget = widgets(index))
	{
		BRect rect = widget->rect();
		if (orientation == Orientation_Horizontal)
		{
			return BRect(rect.right(), rect.top(), handle, rect.height());
		}
		if (orientation == Orientation_Vertical)
		{
			return BRect(rect.left(), rect.bottom(), rect.width(), handle);
		}
	}
	return BRect();
}

void member_BSplitter::adjust()
{
	BRect clientRect = boss->clientRect();
	int x = clientRect.left();
	int y = clientRect.top();

	if (orientation == Orientation_Horizontal)
	{
		float totalWeight = 0;
		for (int i = 0; i < widgets.size(); i++)
		{
			if(widgets[i]->visible())
				totalWeight += widgets[i]->sizeStretch().widthStretch();
		}
		int w = clientRect.width() - (widgets.size() - 1) * handle;
		int h = clientRect.height();
		for(int i = 0; i < widgets.size(); i++)
		{
			BWidget* widget = widgets[i];
			if (!widget->visible())
				continue;
			float widthStretch = widget->sizeStretch().widthStretch();
			int width = w * widthStretch / totalWeight;
			widget->setRect(x, y, width, h);
			x += width + handle;
		}
	}
	if (orientation == Orientation_Vertical)
	{
		BSize minSize;
		float totalWeight = 0;
		for (int i = 0; i < widgets.size(); i++)
		{
			BWidget* widget = widgets[i];
			if (widget->visible())
			{
				totalWeight += widget->sizeStretch().heightStretch();
				minSize.width() = bMax(minSize.width(), widget->minSize().width());
				minSize.height() += widget->minSize().height();
			}
		}
		int w = clientRect.width();
		int h = clientRect.height() - (widgets.size() - 1) * handle;
		
		for(int i = 0; i < widgets.size(); i++)
		{
			BWidget* widget = widgets[i];
			if (!widget->visible())
				continue;
			float heightStretch = widget->sizeStretch().heightStretch();
			int height = h * heightStretch / totalWeight;
			widget->setRect(x, y, w, height);
			y += height + handle;
		}
	}
	dirty = false;
}

void member_BSplitter::dragHandle(const BPoint& pos)
{
	if (handleIndex < 0)
		return;

	BWidget* widget0 = widgets[handleIndex];
	BWidget* widget1 = widgets[handleIndex+1];
	if (orientation == Orientation_Horizontal)
	{
		float weight0 = widget0->widthStretch();
		float weight1 = widget1->widthStretch();
		float totalWeigth = weight0 + weight1;
		float width0 = widget0->width();
		float width1 = widget1->width();
		float totalWidth = width0 + width1;
		float change = pos.x() - pressPos.x();
		weight0 = (width0 + change) / totalWidth * totalWeigth;
		weight1 = (width1 - change) / totalWidth * totalWeigth;
		widget0->setSizeStretch(weight0);
		widget1->setSizeStretch(weight1);
	}
	if (orientation == Orientation_Vertical)
	{
		float weight0 = widget0->heightStretch();
		float weight1 = widget1->heightStretch();
		float totalWeigth = weight0 + weight1;
		float height0 = widget0->height();
		float height1 = widget1->height();
		float totalHeight = height0 + height1;
		float change = pos.y() - pressPos.y();
		weight0 = (height0 + change) / totalHeight * totalWeigth;
		weight1 = (height1 - change) / totalHeight * totalWeigth;
		widget0->setSizeStretch(weight0);
		widget1->setSizeStretch(weight1);
	}
	pressPos = pos;
}
